#include"TcpConnection.hh"
#include<iostream>
#include<sstream>

using std::ostringstream;

TcpConnection::TcpConnection(int fd,Eventpool* rhs)
    :_sock(fd)
    ,_io(fd)
    ,_localaddr(getlocaladdr())
     ,_peeraddr(getpeeraddr())
     ,_event(rhs)
{}

TcpConnection::~TcpConnection()
{

}

void TcpConnection::send(string msg)
{
    _io.write(msg.size(),msg.c_str());
}

string TcpConnection::recv()
{
    char buf[65535]={0};
    _io.readline(sizeof(buf),buf);
    return string(buf);
}

void TcpConnection::SetCloseCallback(func_call&& rhs)
{
    _onclose=rhs;
}

void TcpConnection::SetNewconnCallback(func_call&& rhs)
{
    _onmsg=rhs;
}

void TcpConnection::SetNewMsgCallback(func_call&& rhs)
{
    _onnewconn=rhs;
}

void TcpConnection::handleClosecall()
{
    if(_onclose)
    {
        _onclose(shared_from_this());
    }
    else
    {
        perror("_onclose == nullptr");
    }
}

void TcpConnection::handleConncall()
{
    if(_onnewconn)
    {
        _onnewconn(shared_from_this());
    }
    else
    {
        perror("_onnewconn == nullptr");
    }
}

void TcpConnection::handleMsgcall()
{
    if(_onmsg)
    {
        _onmsg(shared_from_this());
    }
    else
    {
        perror("_onmsg == nullptr");
    }
}

string TcpConnection::to_string()
{
    
    ostringstream oss ;
    oss << "("<<_localaddr.ip()<<" , "
        <<_localaddr.port()<<")"
        <<"------->"
        <<"("<<_peeraddr.ip()<<" , "
        <<_peeraddr.port()<<")";
    return oss.str();
}

bool TcpConnection::is_closed()  const
{
    char buf[10]={0};
    int ret = ::recv( _sock.getfd(),buf ,10,MSG_PEEK);
    return 0==ret;
}


//获取地址
InetAddr TcpConnection::getlocaladdr()
{
    struct sockaddr_in tmp;
    socklen_t len = sizeof(tmp);
    int ret = getsockname(_sock.getfd(),(sockaddr*)&tmp,&len);
    if(ret ==-1)
    {
        perror(" getlocaladdr" );
    }
    return InetAddr(tmp);
}

InetAddr TcpConnection::getpeeraddr()
{
    struct sockaddr_in tmp;
    socklen_t len = sizeof(tmp);
    int ret = getpeername(_sock.getfd(),(sockaddr*)&tmp,&len);
    if(ret ==-1)
    {
        perror(" getpeeraddr" );
    }
    return InetAddr(tmp);
}
   void TcpConnection::sendinpoll(string msg)
{
    _event->runInLoop(std::bind(&TcpConnection::send,this,msg));
}
